package com.konsung.ksdc.manager.machine;

import android.app.ProgressDialog;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.QueryBuilder;
import com.konsung.ksdc.R;
import com.konsung.ksdc.bean.netbean.GroupNetBean;
import com.konsung.ksdc.bean.netbean.RegisterUserNetBean;
import com.konsung.ksdc.common.database.DatabaseHelper;
import com.konsung.ksdc.common.network.RequestCallback;
import com.konsung.ksdc.common.network.RequestUtils;
import com.konsung.ksdc.common.network.ResponseBean;
import com.konsung.ksdc.common.thirdpart.zxing.camera.CameraManager;
import com.konsung.ksdc.common.thirdpart.zxing.decoding.CaptureActivityHandler;
import com.konsung.ksdc.common.thirdpart.zxing.decoding.InactivityTimer;
import com.konsung.ksdc.common.thirdpart.zxing.decoding.RGBLuminanceSource;
import com.konsung.ksdc.common.thirdpart.zxing.view.ViewfinderView;
import com.konsung.ksdc.common.utils.Constants;
import com.konsung.ksdc.common.utils.ToastUtils;
import com.konsung.ksdc.config.NetConfig;
import com.konsung.ksdc.manager.appmain.BaseActivity;
import com.konsung.ksdc.manager.community.ContactIndexActivity;
import com.konsung.ksdc.manager.community.GroupChatActivity;
import com.konsung.ksdc.manager.community.JionGoupActivity;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import okhttp3.Call;

/**
 * 二维码扫描页面
 */
public class MipcaActivityCapture extends BaseActivity implements Callback, View.OnClickListener {

    private CaptureActivityHandler handler;
    private ViewfinderView viewfinderView;
    private boolean hasSurface;
    private Vector<BarcodeFormat> decodeFormats;
    private String characterSet;
    private InactivityTimer inactivityTimer;
    private MediaPlayer mediaPlayer;
    private boolean playBeep;
    private static final float BEEP_VOLUME = 0.10f;
    private boolean vibrate;

    private static final int REQUEST_CODE = 100;
    private static final int PARSE_BARCODE_SUC = 300;
    private static final int PARSE_BARCODE_FAIL = 303;
    private ProgressDialog progressDialog;
    private String photoPath;
    private Bitmap scanBitmap;
    public static final String SCAN_TYPE_CODE = "scan_type_code";
    public static final String TYPE_ADD_CONTACT = "1";
    public static final String TYPE_RELATE_MACHINE = "2";
    private String scanType;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_capture);

        //ViewUtil.addTopView(getApplicationContext(), this, R.string.scan_card);
        CameraManager.init(getApplication());
        viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);

        Button mButtonBack = (Button) findViewById(R.id.button_back);
        mButtonBack.setOnClickListener(this);
        hasSurface = false;
        inactivityTimer = new InactivityTimer(this);
        scanType = getIntent().getStringExtra(SCAN_TYPE_CODE);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_back:
                this.finish();
                break;
            default:
                break;
        }
    }

    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            progressDialog.dismiss();
            switch (msg.what) {
                case PARSE_BARCODE_SUC:
                    onResultHandler((String) msg.obj, scanBitmap);
                    break;
                case PARSE_BARCODE_FAIL:
                    Toast.makeText(MipcaActivityCapture.this, (String) msg.obj,
                            Toast.LENGTH_LONG).show();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onActivityResult(int requestCode,
            int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case REQUEST_CODE:
                    //获取选中图片的路径
                    Cursor cursor = getContentResolver().query(data.getData(),
                            null, null, null, null);
                    if (cursor.moveToFirst()) {
                        photoPath = cursor.getString(cursor.getColumnIndex(
                                MediaStore.Images.Media.DATA));
                    }
                    cursor.close();

                    progressDialog = new ProgressDialog(MipcaActivityCapture.this);
                    progressDialog.setMessage(getString(R.string.pd_scanning));
                    progressDialog.setCancelable(false);
                    progressDialog.show();

                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Result result = scanningImage(photoPath);
                            if (result != null) {
                                Message m = mHandler.obtainMessage();
                                m.what = PARSE_BARCODE_SUC;
                                m.obj = result.getText();
                                mHandler.sendMessage(m);
                            } else {
                                Message m = mHandler.obtainMessage();
                                m.what = PARSE_BARCODE_FAIL;
                                m.obj = "Scan failed!";
                                mHandler.sendMessage(m);
                            }
                        }
                    }).start();

                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 扫描二维码图片的方法
     * @param path 照片路径
     * @return 二维码数据类
     */
    public Result scanningImage(String path) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
        hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); //设置二维码内容的编码

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true; // 先获取原大小
        scanBitmap = BitmapFactory.decodeFile(path, options);
        options.inJustDecodeBounds = false; // 获取新的大小
        int sampleSize = (int) (options.outHeight / (float) 200);
        if (sampleSize <= 0) {
            sampleSize = 1;
        }
        options.inSampleSize = sampleSize;
        scanBitmap = BitmapFactory.decodeFile(path, options);
        RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap);
        BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
        QRCodeReader reader = new QRCodeReader();
        try {
            return reader.decode(bitmap1, hints);
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (ChecksumException e) {
            e.printStackTrace();
        } catch (FormatException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onResume() {
        super.onResume();
        SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
        SurfaceHolder surfaceHolder = surfaceView.getHolder();
        if (hasSurface) {
            initCamera(surfaceHolder);
        } else {
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        decodeFormats = null;
        characterSet = null;

        playBeep = true;
        AudioManager audioService = (AudioManager) getSystemService(
                AUDIO_SERVICE);
        if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
            playBeep = false;
        }
        initBeepSound();
        vibrate = true;
    }

    @Override
    protected String activityDesc() {
        return getString(R.string.page_zing_scan);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (handler != null) {
            handler.quitSynchronously();
            handler = null;
        }
        CameraManager.get().closeDriver();
    }

    @Override
    protected void onDestroy() {
        inactivityTimer.shutdown();
        super.onDestroy();
    }

    /**
     * 处理扫描结果
     * @param result 二维码数据类
     * @param barcode 标示
     */
    public void handleDecode(Result result, Bitmap barcode) {
        inactivityTimer.onActivity();
        playBeepSoundAndVibrate();
        String resultString = result.getText();
        onResultHandler(resultString, barcode);
    }

    /**
     * 跳转到上一个页面
     * @param resultString 字符串key
     * @param bitmap 位图
     */
    private void onResultHandler(final String resultString, Bitmap bitmap) {
        if (!RequestUtils.checkNetwork(MipcaActivityCapture.this)) {
            return;
        }
        if (TextUtils.isEmpty(resultString)) {
            Toast.makeText(MipcaActivityCapture.this, "Scan failed!",
                    Toast.LENGTH_SHORT).show();
            return;
        }
        switch (scanType) {
            case TYPE_ADD_CONTACT:
                RequestUtils.findContactsByCondition(resultString, new RequestCallback() {
                    @Override
                    public void onError(Call call, Exception e) {
                        ToastUtils.toastContent(MipcaActivityCapture.this, getString(R.string
                                .scan_fail));
                    }

                    @Override
                    public void onResponse(ResponseBean responseBean) {

                        if (responseBean.getResultCode().equals(Constants.REQUEST_OK)) {
                            List<RegisterUserNetBean> users = responseBean.getList(
                                    new TypeToken<List<RegisterUserNetBean>>() {
                                    }.getType());
                            if (null != users && users.size() > 0) {
                                Intent intent = new Intent(MipcaActivityCapture.this,
                                        ContactIndexActivity.class);

                                Gson gson = new Gson();
                                intent.putExtra("data", gson.toJson(users.get(0)));
                                startActivity(intent);
                                MipcaActivityCapture.this.finish();
                            } else {
                                findGroup(resultString);
                            }
                        } else {
                            ToastUtils.toastContent(MipcaActivityCapture.this, getString(R.string
                                    .scan_fail));
                        }
                    }
                });

                break;
            case TYPE_RELATE_MACHINE:
                Intent resultIntent = new Intent();
                Bundle bundle = new Bundle();
                bundle.putString("result", resultString);
                bundle.putParcelable("bitmap", bitmap);
                resultIntent.putExtras(bundle);
                this.setResult(RESULT_OK, resultIntent);
                MipcaActivityCapture.this.finish();
                break;
            default:
                break;
        }
    }

    /**
     * 查找二维码群
     * @param resultString 扫码结果
     */
    private void findGroup(String resultString) {

        RequestUtils.findCommunityById(resultString, new RequestCallback() {
            @Override
            public void onError(Call call, Exception e) {
                ToastUtils.toastContent(MipcaActivityCapture.this, getString(R
                        .string.scan_fail));
            }

            @Override
            public void onResponse(ResponseBean responseBean) {
                if (responseBean.getResultCode().equals(Constants.REQUEST_OK)) {
                    GroupNetBean group = responseBean.getEntity(GroupNetBean.class);
                    if (null != group) {
                        //查到数据的bean类
                        GroupNetBean groupNetBean = findisExistGroup(group.getGroupId());
                        if (groupNetBean == null) {
                            //没有该群组
                            Intent intent = new Intent(MipcaActivityCapture.this,
                                    JionGoupActivity.class);

                            Gson gson = new Gson();
                            intent.putExtra("data", gson.toJson(group));
                            startActivity(intent);
                        } else {
                            //有该群组，跳转到对应的群组

                            Intent intent = new Intent(MipcaActivityCapture.this,
                                    GroupChatActivity.class);
                            intent.putExtra("topicName", group.getGroupId()); //群id
                            startActivity(intent);
                        }
                        MipcaActivityCapture.this.finish();
                    } else {
                        ToastUtils.toastContent(MipcaActivityCapture.this, getString(R
                                .string.scan_fail));
                    }
                } else {
                    ToastUtils.toastContent(MipcaActivityCapture.this, getString(R
                            .string.scan_fail));
                }
            }
        });
    }

    /**
     * 查询本地数据库
     * @param groupId 群组id
     * @return 群组
     */
    private GroupNetBean findisExistGroup(String groupId) {
        try {
            Dao dao = DatabaseHelper.getHelper(this).getDao(GroupNetBean.class);
            QueryBuilder qb = dao.queryBuilder();
            qb.where().eq("groupId", groupId).and().eq("ownerId", NetConfig.
                    currentUser.getUserId());
            List<GroupNetBean> list = dao.query(qb.prepare());
            if (list != null && !list.isEmpty()) {
                return list.get(0);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 初始化相机
     * @param surfaceHolder SurfaceHolder
     */
    private void initCamera(SurfaceHolder surfaceHolder) {
        try {
            CameraManager.get().openDriver(surfaceHolder);
        } catch (IOException ioe) {
            return;
        } catch (RuntimeException e) {
            return;
        }
        if (handler == null) {
            handler = new CaptureActivityHandler(this, decodeFormats,
                    characterSet);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (!hasSurface) {
            hasSurface = true;
            initCamera(holder);
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        hasSurface = false;
    }

    /**
     * 获取ViewfinderView实例
     * @return ViewfinderView
     */
    public ViewfinderView getViewfinderView() {
        return viewfinderView;
    }

    /**
     * 获取handler对象
     * @return Handler对象
     */
    public Handler getHandler() {
        return handler;
    }

    /**
     * 创建ViewfinderView实例
     */
    public void drawViewfinder() {
        viewfinderView.drawViewfinder();
    }

    /**
     * 初始化相机快门声音
     */
    private void initBeepSound() {
        if (playBeep && mediaPlayer == null) {
            // The volume on STREAM_SYSTEM is not adjustable, and users found it
            // too loud,
            // so we now play on the music stream.
            setVolumeControlStream(AudioManager.STREAM_MUSIC);
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnCompletionListener(beepListener);

            AssetFileDescriptor file = getResources().openRawResourceFd(
                    R.raw.beep);
            try {
                mediaPlayer.setDataSource(file.getFileDescriptor(),
                        file.getStartOffset(), file.getLength());
                file.close();
                mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
                mediaPlayer.prepare();
            } catch (IOException e) {
                mediaPlayer = null;
            }
        }
    }

    private static final long VIBRATE_DURATION = 200L;

    /**
     * 开启相机相关系统服务
     */
    private void playBeepSoundAndVibrate() {
        if (playBeep && mediaPlayer != null) {
            mediaPlayer.start();
        }
        if (vibrate) {
            Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
            vibrator.vibrate(VIBRATE_DURATION);
        }
    }

    /**
     * When the beep has finished playing, rewind to queue up another one.
     */
    private final OnCompletionListener beepListener = new OnCompletionListener() {
        public void onCompletion(MediaPlayer mediaPlayer) {
            mediaPlayer.seekTo(0);
        }
    };
}